#pragma once

#include <iostream>
#include <string>
#include <unordered_map>
#include "Socket.hpp"
#include "TcpServer.hpp"
#include <sstream>
#include "Util.hpp"
#include "Log.hpp"

using namespace SocketModule;

const std::string gspace = " ";
const std::string glinespace = "\r\n";
const std::string glinesep = ":";

const std::string webroot = "./wwwroot";
const std::string homepage = "index.html";

class HttpRequest
{
public:
    HttpRequest()
    {
    }

    std::string Serialize()
    {
        return std::string();
    }

    void ParseReqLine(std::string &reqline)
    {
        // GET / HTTP/1.1
        std::stringstream ss(reqline);
        ss >> _method >> _uri >> _version; //>>:提取运算符
    }

    // 我们认为reqstr就是一个完整的http request string
    bool Dserialize(std::string &reqstr)
    {
        // 1.提取请求行
        std::string reqline;
        bool res = Util::ReadOneLine(reqstr, &reqline, glinespace);
        LOG(LogLevel::DEBUG) << reqline;

        // 2.对请求行进行反序列化
        ParseReqLine(reqline);
        LOG(LogLevel::DEBUG) << "_method: " << _method;
        LOG(LogLevel::DEBUG) << "_uri: " << _uri;
        LOG(LogLevel::DEBUG) << "_version: " << _version;
        if (_uri == "/")
        {
            _uri = webroot + _uri + homepage;
        }
        else
        {
            _uri = webroot + _uri;
        }

        return true;
    }

    std::string Uri() { return _uri; }

    ~HttpRequest()
    {
    }

private:
    std::string _method; // 请求方法
    std::string _uri;
    std::string _version;

    std::unordered_map<std::string, std::string> _headers;
    std::string _blankline;
    std::string _text;
};

class HttpResponse
{
public:
    HttpResponse() : _blankline(glinespace)
    {
    }

    std::string Serialize()
    {
        std::string status_line = _version + gspace + std::to_string(_code) + gspace + _desc + glinespace;
        std::string resp_header;
        for (auto &header : _headers)
        {
            std::string line = header.first + glinesep + header.second + glinespace;
            resp_header += line;
        }

        return status_line + resp_header + _blankline + _text;
    }

    void SetTargetFile(const std::string &target)//./wwwroot/a/b/c
    {
        _targetfile = target;
    }

    bool MakeResponse()
    {
        bool res = Util::ReadFileContent(_targetfile,&_text);
        if(!res)
        {
            _code = 404;
            _desc = "Not Found";
        }
    }

    bool Dserialize(const std::string & respstr)
    {
        return true;
    }

    ~HttpResponse()
    {}

//private:
public:
    std::string _version;
    int _code;
    std::string _desc;

    std::unordered_map<std::string, std::string> _headers;
    std::string _blankline;
    std::string _text;

    // 其他属性
    std::string _targetfile;
};

class Http
{
public:
    Http(uint16_t port) : tser(std::make_unique<TcpServer>(port))
    {
    }

    void HandlerHttpRequest(std::shared_ptr<Socket> &socket, InetAddr &client)
    {
        //收到请求
        std::string httprequest;
        //假设我们收到的都是完整的请求
        //bug
        int n = socket->Recv(&httprequest);//也有问题，tcp面相字节流
        if(n>0)
        {
            //对报文完整性进行审核---缺
            HttpRequest req;
            req.Dserialize(httprequest);
            HttpResponse resp;
            resp.SetTargetFile(req.Uri());
            resp.MakeResponse();
            
            HttpResponse resp;
            resp._version = "HTTP/1.1";
            resp._code = 200;
            resp._desc = "Ok";
            //./wwwroot/a/b/c.html
            LOG(LogLevel::DEBUG)<<"用户请求："<<filename;
            bool res = Util::ReadFileContent(filename,&(resp._text));
            (void)res;

            std::string response_str = resp.Serialize();
            socket->Send(response_str);
        }
#ifndef DEBUG
#define DEBUG
        std::string httprequest;
        socket->Recv(&httprequest);
        std::cout << httprequest;

#endif
    }

    void Start()
    {
        tser->Start([this](std::shared_ptr<Socket> &socket, InetAddr &client)
                    { this->HandlerHttpRequest(socket, client); });
    }
    ~Http()
    {
    }

private:
    std::unique_ptr<TcpServer> tser; // 独占式管理动态分配的内存
};